home *** CD-ROM | disk | FTP | other *** search
- "send" for Xt User Manual
- -------------------------
-
- Introduction
- ------------
- Applications in the X world can use a number of X based mechanisms to
- communicate with each other. The most common is to use ``selections'' and
- cut buffers. These are ultimately based on X Properties that can be
- attached to windows.
-
- In the Tk set of widgets, another communication protocol was introduced. In
- this, a Tk application can ``send'' commands to another Tk application. A
- Tk based application is generally built using the programming language tcl,
- and the messages actually consist of tcl commands from the first
- application to the second. This causes the second application to execute
- the command, possibly invoking communications with other applications.
-
- The use of Tk is not essential for this to work - any set of widgets in X
- world can use this mechanism. It is also implemented using the X Properties
- system. This package is an implementation of ``send'' for Xt based
- applications.
-
-
- Using ``send'' in tcl
- ---------------------
- tcl is a type-free interpreted language that uses strings for everything.
- It is intended as a language that can be embedded into applications
- requiring a command language. The language supplies a syntax and a
- semantics, and this is realised by an interpreter that can be created by
- an application. New tcl commands can be defined by the application that
- will call application code when executed by the interpreter. Information
- can be examined and set in the interpreter.
-
- An extension introduced by the Tk toolkit allows one interpreter to execute
- commands in another one. Each interpreter is given a global name within the
- X world. One interpreter can send a command to another one using its name:
-
- send you_over_there do_this_command
-
- For example, a debugger could send a message to an editor
-
- send editor {display_line 42}
-
- The command will be attempted in the other interpreter. This is done
- synchronously, and any result is sent back to the first interpreter. If the
- first interpreter does not receive an reply in a reasonable time (5
- seconds) ``send'' times out with an error value.
-
- This allows small applications to co-operatively execute, much like small
- character based Unix applications do.
-
- ``send'' and Xt
- ---------------
- This package allows an Xt application to send tcl commands to any
- application that understands the ``send'' protocol, and in turn it will
- receive and execute tcl commands sent to it. Both the sending and the
- execution are performed through a tcl interpreter, so the Xt application
- first has to create such an interpreter. This is done by the function call
-
- #include <tcl.h>
-
- Tcl_Interp *Tcl_CreateInterp(void);
-
- This returns a pointer to a tcl interpreter which will be used in all
- successive calls to the tcl system.
-
- More than one interpreter may be created, but most applications would only
- create one.
-
-
- Registering a tcl interpreter
- -----------------------------
- Before an interpreter can be used to send or receive commands, it must be
- registered so that its name is globally known. Any name can be used. A
- convention in Tk based applications is that this will be the name of the
- application, if possible. This allows the user of these applications to see
- the interpreter name as the name shown by the window manager.
-
- There can only be one name per interpreter because of the way ``send'' was
- implemented originally.
-
- A name exists on the server's root window, so interpreter names must be
- unique on a display. An attempt to register a name that is already in use
- will fail.
-
- Registering an interpreter is done by
-
- #include <tcl.h>
- #include <tclXtSend.h>
-
- int TclXtSend_RegisterInterp(Tcl_Interp *interp, char *name, Widget toplevel);
-
- The widget argument can be any widget, but will normally be the widget
- returned from the XtAppInitialize function. The return value of the
- function will either be TCL_OK or TCL_ERROR.
-
- [The rather gross name arise from trying to find a reasonable naming
- convention. Tcl_, Tk_, Xt, X, etc are all reserved by the various toolkits.
- TclXtSend_ shows the origins and does not clash with other names. You only
- have to type it once per application, anyway.]
-
- Communicating with the interpreter from the application
- -------------------------------------------------------
- The simplest way to get the interpreter to execute a command from an
- application is to call Tcl_Eval with the command as the second argument.
- For example,
-
- Tcl_Eval(interp, "puts stdout {hello world}");
-
- This mechanism can be used unaltered to send a message: the command is now
- a ``send'' command:
-
- Tcl_Eval(interp, "send editor {display_line 42}");
-
- The function returns TCL_OK if it succeeds, and TCL_ERROR if it fails. If
- it fails, an error message will be in interp->result.
-
- Communicating with the interpreter via ``send''
- ----------------------------------------------
- Once an interpreter has been registered, another application can use the
- send protocol to cause it to execute commands. Nothing extra has to be
- done.
-
- Interpreter state
- -----------------
- The tcl interpreter maintains the state of the tcl variables known to it.
- The value of one of these can be examined using Tcl_GetVar, and set using
- Tcl_SetVar.
-
- New commands can be defined purely internally to the tcl interpreter using
- the Tcl_Eval function, where the string to be executed defines a tcl
- procedure:
-
- Tcl_Eval(interp, "proc hello {} {puts stdout {hello world}}");
-
- Application commands
- --------------------
- The interpreter can be extended by new commands which call execution code
- by the Tcl_CreateCommand. This takes as arguments the interpreter, the
- command name, the C function to execute when the interpreter executes the
- command, client data that can be passed to the C function, and a destroy
- function if needed.
-
- Examples
- --------
- Supposing you want to send a message to another interpreter when a callback
- occurs. For example, a command panel listing all interpreters could send an
- ``exit'' message to an interpreter when its button is pressed.
-
- In the client data of the button, place the interpreter. This ensures that
- it is ``local'' data rather than mucky global stuff:
-
- XtAddCallback(w, XmNactivateCallback, KillCB, (XtPointer) interp);
-
- Within the callback, extract the interpreter and send the message (say to
- interpreter ``abcd'')
-
- interp = (Tcl_Interp *) client_data;
- Tcl_Eval(interp, "send abcd exit");
-
- On the other hand, if you are the application that may be in receipt of
- such a message, you may want to handle this in a graceful way. So your
- application creates a new command to call your C code when this happens:
-
- Tcl_CreateCommand(interp, "exit", ExitGracefully, NULL, NULL);
-
- int ExitGracefully(ClientData *clientdata, Tcl_Interp *interp,
- int argc, char **argv)
- {
- /* tidy up the application */
- /* .... */
-
- Tcl_DeleteInterp(interp);
- exit(0);
- }
-
- Implementation
- --------------
- The implementation is identical to Tk: create an unmapped window in each
- application known as ``_comm''. Properties are attached to this window to
- receive the message, while an event handler waits on this window for a
- PropertyNotify message.
-
- The root window maintains a list of interpreters and their corresponding
- windows in the property ``InterpRegistry''. This is updated on each change.
-